<?php

namespace app\models;

use app\components\BaseActiveRecord;
use app\utils\BaseUtils;
use app\utils\EncryptUtils;
use Yii;
use yii\web\IdentityInterface;
use yii\web\User;
use yii\web\UserEvent;

/**
 * This is the model class for table "{{%admin}}".
 *
 * @property integer $id
 * @property integer $gid
 * @property string $username
 * @property string $password
 * @property string $author
 * @property string $email
 * @property integer $last_login_time
 * @property integer $last_login_ip
 * @property integer $status
 */
class Admin extends BaseActiveRecord implements IdentityInterface {

    const rememberTime = 259200;

    public $rememberMe = TRUE;

    public $newPwd;
    public $newPwd2;
    public $password2;
    public $captcha;

    public static $statusLabels = [
        self::STATUS_NO => '禁用',
        self::STATUS_YES => '正常',
    ];

    public function init() {
        parent::init();
        $this->newPwd = $this->password2 = '';
        $this->status = static::STATUS_YES;
        Yii::$app->user->on(User::EVENT_AFTER_LOGIN, [$this, 'afterLogin']);
    }

    /**
     * @inheritdoc
     */
    public static function tableName() {
        return '{{%admin}}';
    }

    /**
     * @inheritdoc
     */
    public function rules() {
        return [
            [['username', 'password'], 'required', 'on' => 'login'],

            [['password', 'password2', 'username', 'author', 'email'], 'required', 'on' => 'new'],
            [['password2'], 'compare', 'compareAttribute' => 'password', 'message' => '2次密码不一致', 'on' => 'new'],

            [['newPwd2'], 'compare', 'compareAttribute' => 'newPwd', 'message' => '新密码2次不一致', 'on' => 'save'],
//            [['rePassword'], 'required', 'when' => function ($model) {
//                return !empty($model->newPassword);
//            }, 'whenClient' => "function(attribute){
//                    return $(attribute.container).parent('form').find('#admin-newpassword').val() != '';
//                }", 'on' => 'save'
//            ],

            [['password', 'password2', 'newPwd2', 'newPwd'], 'string', 'min' => 5, 'max' => 16],
            [['gid', 'last_login_time', 'last_login_ip', 'status'], 'integer'],
            [['username'], 'string', 'max' => 60],
            [['email'], 'email'],
            [['author', 'email'], 'string', 'max' => 100],
            //['captcha', 'captcha', 'captchaAction' => '/admin/login/captcha']
        ];
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels() {
        return [
            'id' => 'ID',
            'gid' => '管理组',
            'username' => '用户名',
            'password' => '密码',
            'author' => '姓名',
            'email' => '邮箱',
            'last_login_time' => '最后登录时间',
            'last_login_ip' => 'Last Login Ip',
            'status' => '状态',
            'rememberMe' => '3天内免登录',
            'password2' => '重复密码',
            'newPwd2' => '重复新密码',
            'newPwd' => '新密码',
        ];
    }

    /**
     * Finds an identity by the given ID.
     * @param string|integer $id the ID to be looked for
     * @return IdentityInterface the identity object that matches the given ID.
     * Null should be returned if such an identity cannot be found
     * or the identity is not in an active state (disabled, deleted, etc.)
     */
    public static function findIdentity($id) {
        return static::find()->with('group')->where(['id' => $id])->one();
    }

    /**
     * Finds an identity by the given token.
     * @param mixed $token the token to be looked for
     * @param mixed $type the type of the token. The value of this parameter depends on the implementation.
     * For example, [[\yii\filters\auth\HttpBearerAuth]] will set this parameter to be `yii\filters\auth\HttpBearerAuth`.
     * @return IdentityInterface the identity object that matches the given token.
     * Null should be returned if such an identity cannot be found
     * or the identity is not in an active state (disabled, deleted, etc.)
     */
    public static function findIdentityByAccessToken($token, $type = NULL) {
        // TODO: Implement findIdentityByAccessToken() method.
    }

    /**
     * Returns an ID that can uniquely identify a user identity.
     * @return string|integer an ID that uniquely identifies a user identity.
     */
    public function getId() {
        return $this->id;
    }

    /**
     * Returns a key that can be used to check the validity of a given identity ID.
     *
     * The key should be unique for each individual user, and should be persistent
     * so that it can be used to check the validity of the user identity.
     *
     * The space of such keys should be big enough to defeat potential identity attacks.
     *
     * This is required if [[User::enableAutoLogin]] is enabled.
     * @return string a key that is used to check the validity of a given identity ID.
     * @see validateAuthKey()
     */
    public function getAuthKey() {
        return EncryptUtils::md516(APP_KEY);
    }

    /**
     * Validates the given auth key.
     *
     * This is required if [[User::enableAutoLogin]] is enabled.
     * @param string $authKey the given auth key
     * @return boolean whether the given auth key is valid.
     * @see getAuthKey()
     */
    public function validateAuthKey($authKey) {
        return EncryptUtils::md516(APP_KEY) === $authKey;
    }

    public function login() {
        if (!$this->validate()) {
            return static::retErr($this->getError());
        }

        $user = static::findOne(['username' => $this->username]);
        if (!$user) {
            return static::retErr('用户不存在。');
        }
        $_pass = EncryptUtils::md516($this->password);
        if ($_pass != $user['password']) {
            return static::retErr('密码错误。');
        }
        if (!$user->getIsActive()) {
            return static::retErr('该帐号已禁止。');
        }
        $this->id = $user->id;

        Yii::$app->user->login($user, $this->rememberMe ? self::rememberTime : 0);
        return static::retOK(['redirect' => Yii::$app->user->getReturnUrl(['/admin'])]);
    }

    public function afterLogin(UserEvent $event) {
        /* @var $user Admin */
        $user = $event->identity;
        if (!$user->getIsNewRecord()) {
            $user->last_login_ip = BaseUtils::getClientIp();
            $user->last_login_time = time();
            $user->save();
        }
    }

    public function saveAdmin() {
        if (!$this->validate()) {
            return static::retErr($this->getError());
        }
        if ($this->isNewRecord) {
            $this->password = EncryptUtils::md516($this->password);
            $this->password2 = EncryptUtils::md516($this->password2);
        } else {
            if (!empty($this->newPwd)) {
                $this->password = EncryptUtils::md516($this->newPwd);
            }
        }
        return $this->save();
    }

    public static function loginUserIsRoot() {
        $_uid = intval(Yii::$app->user->id);
        return $_uid === 1 && Yii::$app->user->identity->username === 'root';
    }

    public function getGroup() {
        return $this->hasOne(AdminGroup::className(), ['id' => 'gid']);
    }

    public function getIsActive() {
        return intval($this->status) === self::STATUS_YES;
    }

    public function getIsDisable() {
        return intval($this->status) === self::STATUS_NO;
    }
}
